package com.lin.cloud.disk.manage.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.lin.cloud.disk.common.utils.DataUtil;
import com.lin.cloud.disk.entity.dto.DepartmentDTO;
import com.lin.cloud.disk.entity.pojo.Department;
import com.lin.cloud.disk.entity.request.company.AddCompanyInfoRequest;
import com.lin.cloud.disk.entity.request.company.GetCompanyDepartmentTreeRequest;
import com.lin.cloud.disk.manage.ICompanyManageService;
import com.lin.cloud.disk.service.ICompanyDepartmentService;
import com.lin.cloud.disk.service.ICompanyService;
import com.lin.cloud.disk.service.ICompanyStatusService;
import com.lin.cloud.disk.service.IDepartmentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author ljc
 * @date 2021/1/12 19:27
 */
@Service
@Slf4j
public class CompanyManageServiceImpl implements ICompanyManageService {

    @Resource
    private ICompanyDepartmentService companyDepartmentService;

    @Resource
    private IDepartmentService departmentService;

    @Resource
    private ICompanyService companyService;

    @Resource
    private ICompanyStatusService companyStatusService;

    /**
     * 获取公司所有的部门
     * @param request
     * @return
     */
    @Override
    public List<DepartmentDTO> getCompanyDepartmentList(GetCompanyDepartmentTreeRequest request){

        // 获取公司所有的部门ID列表
        List<Long> departmentIdList= companyDepartmentService.getDepartmentIdListByCompany(request.getUserDTO().getCompanyId());
        if (CollectionUtils.isNotEmpty(departmentIdList)){
            // 获取部门详细信息
            List<Department> departmentList = departmentService.selectDepartmentByDepartmentIdList(departmentIdList);
            if (CollectionUtils.isNotEmpty(departmentList)){
                // 转为JSON ARRAY
                JSONArray array = JSONArray.parseArray(JSON.toJSONString(departmentList));
                array = DataUtil.listToTree(array, "id", "parentId", "children");
                List<DepartmentDTO> responseList  = array.toJavaList(DepartmentDTO.class);
                // 统计子节点数量
                this.getSubDepartmentCount(responseList);
                return responseList;
            }
        }
        return Collections.emptyList();
    }



    /**
     * 添加公司主体信息
     * @param request
     */
    @Override
    public void addCompanyInfo(AddCompanyInfoRequest request){
        // 添加公司主体
        Long companyId = companyService.addCompanyInfo(request);
//        // 添加公司主体信息流转日志
//        CompanyStatus companyStatus = new CompanyStatus();
//        companyStatus.setCompanyId(companyId);
//        companyStatus.setCompanyName(request.getCompanyName());
//        companyStatus.setCreateBy(request.getCreateBy());
//        companyStatus.setCreateTime(new Date());
//        // 默认状态
//        companyStatus.setStatus(ECompanyStatus.WAIT_REVIEW.getStatus());
//        // 设置流转信息
//        String circulationMsg = String.format("创建公司: %s, 当前公司状态: %s",companyStatus.getCompanyName(),ECompanyStatus.WAIT_REVIEW.getStatus());
//        companyStatus.setCirculationMsg(circulationMsg);
//        companyStatusService.saveCompanyStatus(companyStatus);
    }


    /**
     * 获取子部门数量总和
     * @param departmentDTOList
     */
    private void getSubDepartmentCount(List<DepartmentDTO> departmentDTOList){
        // 列表为空则不计算
        if (CollectionUtils.isEmpty(departmentDTOList)){
            return;
        }
        // 遍历列表中所有数据 以父层的纬度计算子层的数据总量
        for(DepartmentDTO departmentDTO : departmentDTOList){
            // 统计父层之下数据总量
            this.countChild(departmentDTO);
        }
    }
    /**
     * 统计父层之下数据总量
     * @param parentDepartmentDTO
     * @return
     */
    private int countChild(DepartmentDTO parentDepartmentDTO){
        // 无序判断parentDepartmentDTO对象是否存在 能进去则代表存在
        // 如果父层没有子层 则返回0
        if (CollectionUtils.isEmpty(parentDepartmentDTO.getChildren())){
            return 0;
        }
        // totalCount 该层之下所有的总量 默认为0
        int totalCount = 0;
        // 遍历该层之下所有数据
        for(DepartmentDTO departmentDTO : parentDepartmentDTO.getChildren()){
            // 有一个元素则+1
            totalCount++;
            // 该元素继续往下递归 则到他的子层不存在返回
            // 将全部数量加入该层的总量下
            totalCount += this.countChild(departmentDTO);
        }
        // 设置该层的总量数据
        parentDepartmentDTO.setChildrenTotalCount(totalCount);
        // 返回给上一层
        return totalCount;
    }

    /**
     * 使用map统计统计
     * @param departmentDTOList
     * @param stack
     * @param map
     */
    private void countChild(List<DepartmentDTO> departmentDTOList, Stack<DepartmentDTO> stack, Map<Long,Integer> map){
        if (CollectionUtils.isEmpty(departmentDTOList)){
            return;
        }
        for(DepartmentDTO departmentDTO : departmentDTOList){
            // 先入栈
            stack.push(departmentDTO);
            // 深度遍历子层
            this.countChild(departmentDTO.getChildren(),stack,map);
            // 将本身弹出 统计本身之前的
            stack.pop();
            // 子层遍历完后 统计
            stack.forEach(item ->{
                Long id = item.getId();
                int size = map.get(id) == null ? 1 : map.get(id) + 1;
                map.put(id,size);
            });

        }


    }
}
